<?php

namespace app\admin\controller\flow;

use app\common\controller\Backend;
use think;
use fast\Date;
use think\Db;
use think\Config;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;
use fast\Random;
use app\admin\library\Auth;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;

/**
 * 
 *
 * @icon fa fa-circle-o
 */
class Jimu extends Backend
{
    /**
     * View模型对象
     * @var \app\admin\model\lowcode\View
     */
    protected $model = null;
    protected $viewmodel = null;
    protected $field = null;
    protected $entity = null;
    protected $form = null;
    protected $noNeedRight = ['*'];
    protected $entity_id = null;

    public function _initialize()
    {
        $this->field = new \app\admin\model\lowcode\Field;
        $this->entity = new \app\admin\model\lowcode\Entity;
        $this->form = new \app\admin\model\lowcode\Form;
        $this->adminModel = new \app\admin\model\Admin();
        $this->viewmodel = new \app\admin\model\lowcode\View;
        parent::_initialize();
        $this->prefix = Config::get('database.prefix');
        $this->entity_id = $this->request->request("entity_id");
    }
    /**
     * 获取looup字段 view视图字段 第一次加载获取此方法
     */
    public function getData($id = '')
    {
        $result = null;
        $id = $this->request->request("id");
        $entity_id = $this->entity_id;
        if (!$entity_id) {
            $entity_id = $this->request->request("entity_id");
        }
        if (!$entity_id) {
            json('缺少参数', 500);
        }
        $rowEntity = $this->entity->get($entity_id);
        $data[] = [
            'label' => $rowEntity['name'],
            'value' => $rowEntity['code'],
            'lookup_id' => $entity_id,
            'disabled' => false,
            'default' => true
        ];
        $fieldListAll = $this->field
            ->where(['entity_id' => $entity_id, 'fieldtype' => 'lookup', 'default' => 0])
            ->select();
        foreach ($fieldListAll as $row) {
            $data[] = [
                'label' => $row['fieldname'],
                'value' => $row['fieldcode'],
                'lookup_id' => $row['lookup_id'],
                'disabled' => false,
                'default' => false
            ];
        }

        //获取当前视图名称和是否自适应宽度
        $id = $this->request->request("id");
        $fieldListAll = $this->viewmodel
            ->where(['id' => $id])
            ->select();

        $result['lookup'] = $data;
        $result['view'] = $fieldListAll;
        $result['viewId'] = $id;
        $result['entityCode'] = $rowEntity['code'];

        return json($result);
    }

    /**获取视图字段 */
    public function getview()
    {
        if (!$this->entity_id) {
            return json('缺少参数', 500);
        }
        $data = null;
        $columns = null;
        $viewList = null;
        $id = $this->entity_id;
        $event = $this->request->request("event");
        $page = $this->request->post("page/a");
        $rowEntity = $this->entity->get($id);
        $where = ['entity_id' => $id, 'status' => 'normal'];
        //获取列/视图列表 排序获取默认视图
        $fieldListAll = $this->viewmodel
            ->where($where)
            ->order('viewtype asc')
            ->select();
        foreach ($fieldListAll as $item) {
            if ($event == 'change') {
                $columns = $item['columns'];
            } else {
                $columns = $fieldListAll[0]['columns'];
            }
            $viewList[] = [
                'label' => $item['viewname'],
                'value' => $item['id'],
                'disabled' => false
            ];
        }
        $data['viewlist'] = $viewList;
        $data['columns'] = $columns;
        if ($event) {
            $id = $fieldListAll[0]['entity_id'];
        }

        //获取表格数据

        $list = $this->getTableData($viewList[0]["value"], $page);
        $data['data'] = $list;
        $data['entity_id'] = $id;
        $data['idfield'] = $rowEntity->code . 'id';
        //获取表单
        $formrow = $this->form->where(['entity_id' => $id, 'isdefault' => '1'])->find();
        if ($formrow) {
            $data['formJson'] = $formrow->formjson;
        }
        $data['buttons'] = $this->build_toolbar($rowEntity->code);
        return json($data);
    }

    /**获取视图数据 */
    public function getViewData()
    {
        $id = $this->request->request("viewid");
        $page = $this->request->post("page/a");
        $sort = $this->request->post("sort/a");
        $quicksearch = $this->request->request('quicksearchValue');
        $filter = $this->request->post("filter/a");
        $list = $this->getTableData($id, $page, $quicksearch, $sort, $filter);
        return Json($list);
    }
    /**获取视图数据 */
    public function getTableData($viewid, $page, $quicksearch = '', $sort = [], $filter = [])
    {
        try {
            $result = null;
            $sortSql = "";
            $quicksearchSql = "";
            $conditionSql = "";
            $whereSql = "";
            //获取表格数据
            $entityview = $this->viewmodel->get($viewid);
            $entityrow = $this->entity->get($entityview->entity_id);
            $tableviewname = $entityrow->code . 'view';

            if (!$entityview) {
                return json('');
            }
            $viewcondition = $entityview->condition;

            $viewquicksearch = $entityview->quicksearch;
            if (count($sort) > 0 && $quicksearch == '') {
                $sortSql = " order by ";
                foreach ($sort as $i) {
                    $sortSql .= $i['field'] . ' ' . $i['order'] . ',';
                }
                $sortSql = rtrim($sortSql, ',');
            }
            if (count($filter) > 0 && $quicksearch == '') {
                $whereSql = "  where 1=1 and ";
                foreach ($filter as $j) {
                    switch ($j['templete']) {
                        case 'text_filter':
                            switch ($j['type']) {
                                case 'eq':
                                    $whereSql .= ' '.$j['field'] . " = '" . $j['value'] . "' and";
                                    break;
                                case 'contain':
                                    $whereSql .= ' '.$j['field'] . ' like '."'%" . $j['value'] . "%' and";
                                    break;
                            }
                            break;
                        case 'date_filter':
                            $whereSql .= ' '.$j['field'] . " between  '" . $j['value']['begin'] . "' and '". $j['value']['end'] ."' and";
                            break;
                    }
                }
                $whereSql = rtrim($whereSql, 'and');
            }
            if ($viewcondition) {
                $conditonArry = json_decode($viewcondition, true);
                
                $conditionSql = " where ";
                foreach ($conditonArry as $key => $v) {
                    switch ($v['operatetype']) {
                        case 'eq':
                            $conditionSql .= ' '."$tableviewname." . $v['fieldcode'] . " = '" . $v['fieldvalue'] . "' and";
                            break;
                        default:
                            break;
                    }
                }
                $conditionSql = rtrim($conditionSql, 'and');
            }
            if ($quicksearch) {
                if ($viewquicksearch) {
                    $quickArry = json_decode($viewquicksearch, true);
                    $quickSql = "(  ";
                    foreach ($quickArry as $key => $v) {
                        $quickSql .= ' '."$tableviewname." . $v['fieldcode'] . "  like  '%" . $quicksearch . "%' or";
                    }
                    $quickSql = rtrim($quickSql, 'or');
                    $quickSql.=" )";
                    $quicksearchSql = " and  $quickSql";
                } else {
                    $quicksearchSql = " where  $tableviewname.name like '%$quicksearch%'  or $tableviewname.code like '%$quicksearch%'";
                }
            }
            $sql = 'select * from (' . $entityview->sql . $conditionSql . $quicksearchSql . ') a ' . $whereSql;
            $index = $page['currentPage'];

            $size = $page['pageSize']=='1' ? 5000: $page['pageSize'];
            $limit = " limit " . ($index - 1) * $size . ",$size";
            $list = Db::query($sql . $sortSql . $limit);
            $total = Db::query("select count(1) as total from ($sql) a");
            $result['list'] = $list;
            $result['total'] = $total[0]["total"];
            $result['columns'] = $entityview['columns'];
        } catch (Exception $e) {
            return $this->error('获取数据失败', 500);
        }

        return $result;
    }





    /**获取表单 */
    public function getform($entity_id = "")
    {
        if (!$this->entity_id) {
            return json('缺少参数', 500);
        }
        $row = $this->form->where(['entity_id' => $entity_id, 'isdefault' => '1'])->find();
        return Json(["formJson" => $row->formjson]);
    }

    /**获取下拉框数据 */
    public function getselectbyfield()
    {
        $entity_id = $this->request->request("entity_id");
        $field = $this->request->request("field");
        $fielRow = Db::name('lowcode_field')->where(['entity_id' => $entity_id, 'fieldcode' => $field])->find();
        $row = Db::name('lowcode_metadata')->field('label,value')->where(['name' => $fielRow['metadata']])->select();
        $result['data'] = $row;
        $result['code'] = 1;
        return Json($row);
    }

    /**获取实体 */
    public function getentityrow()
    {
        if (!$this->entity_id) {
            return json('缺少参数', 500);
        }
        $entity_id = $this->request->get("entity_id");
        $id = $this->request->get("id");
        $entityrow = $this->entity->get($entity_id);
        $fieldid = $entityrow->code . 'id';
        if (!$entityrow) {
            $this->error(__('No Results were found'));
        }
        $datarow = Db::table($entityrow->code . 'view')->where([$entityrow->code . 'id' => $id])->find();
        $fieldListAll = $this->field
            ->where(['entity_id' => $entity_id])
            ->select();
        $result = [];
        foreach ($fieldListAll as $item => $row) {
            $fieldcode = $row->fieldcode;
            $fieldtype = $row->fieldtype;
            if (isset($datarow[$fieldcode])) {
                
                switch ($fieldtype) {
                    case 'lookup':
                        $result[$fieldcode] = ['id' => $datarow[$fieldcode], 'name' => $datarow[$fieldcode . 'name']];
                        break;
                    case 'select':
                        $result[$fieldcode] = $datarow[$fieldcode];
                        break;
                    case 'subform';
                        break;
                    default:
                        $result[$fieldcode] =$this->isJson($datarow[$fieldcode]);
                        break;
                }
            }
            else
            {
                $result[$fieldcode] = '';
            }
        }
        return Json($result);
    }
    /**获取lookup字段 */
    public function getlookupview()
    {
        if (!$this->entity_id) {
            return json('缺少参数', 500);
        }
        $entity_id = $this->request->request("entity_id");
        $field = $this->request->request("field");
        $fielRow = Db::name('lowcode_field')->where(['entity_id' => $entity_id, 'fieldcode' => $field])->find();
        $row = Db::name('lowcode_metadata')->where(['name' => $fielRow['metadata']])->select();
        $page = $this->request->post("page/a");
        $size = $page['size'];
        $pageIndex = $page['pageIndex'];
        $search = $page['search'];
        if(!$fielRow){
            $entityList = [];
        }
        else{
            $lookupid = $fielRow['lookup_id'];
            $tablecode = $this->entity->get($lookupid);
            $count = Db::table($tablecode->code)->where(['status'=>'normal'])->count();
            if($search){
                $entityList = Db::table($tablecode->code)                  
                    ->whereOr('code','like',"%$search%")
                    ->whereOr('name','like',"%$search%")
                    ->where(['status'=>'normal'])
                    ->page($pageIndex,$size)->select();
            }else{
                $entityList = Db::table($tablecode->code)
                    ->where(['status'=>'normal'])
                    ->page($pageIndex,$size)->select();
            }
            
        }
        
        $data['tableHead'] = [
            ['field' => 'id', 'title' => 'id'],
            ['field' => 'code', 'title' => '编码'],
            ['field' => 'name', 'title' => '名称'],
            ['field' => 'createtime', 'title' => '创建时间']
        ];
        $data['tableData'] = $entityList;
        $data['total'] = $count;
        $data['fieldid'] = 'id';
        $result['data'] = $data;
        $result['result'] = 1;
        return Json($result);
    }

    /**获取lookup字段 */
    function build_toolbar($code,$attr = [])
    {
        $code=str_replace('_','',str_replace($this->prefix.'lowcode_','',$code)) ;
        $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
        //$btns = $btns ? $btns : ['add', 'edit', 'del', 'import', 'multi'];
        //$btns = is_array($btns) ? $btns : explode(',', $btns);
        //获取所有操作
        $btmList= Db::name('auth_rule')
                  ->where(['ismenu'=>'0','status'=>'normal'])
                  ->where('name','like',"lowcode/$code/%")->order('id asc')->select();


        $btnAttr = [
            'add'  => ['添加', 'my-insert', 'fa fa-plus'],
            'edit'    => ['编辑', 'my-insert', 'fa fa-plus'],
            'del'  => ['删除', 'danger', 'fa fa-plus'],
            'import'  => ['导入', 'success', 'fa fa-plus'],
            'multi'  => ['更多', 'success', 'fa fa-plus'],
        ];
        $btnAttr = array_merge($btnAttr, $attr);
        $html = [];
        foreach ($btmList as $k => $row) {
            $arr =explode('/',$row['name']);
            $v =  end($arr);
            if($v == 'index')
                continue;
            //如果未定义或没有权限
            if (($v !== 'refresh' && $this->auth->check("lowcode/$code/{$v}"))) {
                if(!array_key_exists($v,$btnAttr)){
                    $itm = ['code' => $v, 'name' =>  $row['title'], 'status' => 'my-insert', 'icon' => 'fa fa-plus'];
                    $html[] = $itm;
                }
                else if ($v == 'import') {
                    $itm = ['code' => 'vxeimport', 'name' => $btnAttr[$v][0], 'status' => $btnAttr[$v][1], 'icon' => $btnAttr[$v][2]];
                    $html[] = $itm;
                } else if ($v == 'multi') {
                    $html[] = [
                        'name' => '更多', 'status' => 'info', 'disabled' => false,
                        'dropdowns' => [
                            ['code' => 'normal', 'name' => '设为正常', 'status' => 'info', 'icon' => 'fa fa-plus'],
                            ['code' => 'hidden', 'name' => '设为隐藏', 'status' => 'info', 'icon' => 'fa fa-plus'],
                        ]
                    ];
                } else {
                    $itm = ['code' => $v, 'name' => $btnAttr[$v][0], 'status' => $btnAttr[$v][1]];
                    $html[] = $itm;
                }
            } else {
                continue;
            }
        }

        return $html;
    }

    /**添加/编辑实体 */
    public function saveentityrow($ids = null)
    {
        if (!$ids) {
            return json('缺少参数', 500);
        }
        $entityrow = $this->entity->get($ids);
        if (!$entityrow) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($entityrow[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("data/a");
            if ($params) {
                //获取当前表单所有参数
                $fieldListAll = $this->field
                    ->where(['entity_id' => $ids])
                    ->select();
                $result = [];
                $action = $params['action'];
                $subformdata = null;
                foreach ($fieldListAll as $item => $row) {
                    $fieldcode = $row->fieldcode;
                    $fieldtype = $row->fieldtype;
                    //判断是否存在数据，在判断是否是子表通过是不是数组判断
                    if ((array_key_exists($fieldcode, $params))) {
                        switch ($fieldtype) {
                            case 'lookup':
                                $result[$fieldcode] = $params[$fieldcode]['id'];
                                break;
                            case 'image':
                            case 'file':
                                if (is_array($params[$fieldcode])) {
                                    $fieldata = [];
                                    foreach($params[$fieldcode] as $file){
                                        if(!empty($file['response'])){
                                            $file['url'] = $file['response']['url'];
                                        }
                                        $fieldata[] = $file;
                                    }
                                    $result[$fieldcode] = json_encode($fieldata);
                                }
                                break;
                            case 'subform';
                                $subform_lookup_id = $row->lookup_id;
                                $subformdata[$fieldcode] = ['entity_id' => $subform_lookup_id, 'data' => $params[$fieldcode]];
                                break;
                            default:
                                if (is_array($params[$fieldcode])) {
                                    $result[$fieldcode] = json_encode($params[$fieldcode]);
                                } else {
                                    $result[$fieldcode] = $params[$fieldcode];
                                }

                                break;
                        }
                    }
                }
                
                $result['updateby'] = $this->auth->id; 
                $result['updatetime'] = date("Y-m-d H:i:s");
                //判断是否自动生成code
                $success = false;
                $successid = '';
                Db::startTrans();
                try {
                    if ($action == 'add') {
                        $result['createby'] = $this->auth->id;
                        $result['createtime'] = date("Y-m-d H:i:s");
                        //先保存主表
                        $successid = Db::table($entityrow->code)->insertGetId($result);
                    } else {
                        $result['id'] = $params['id'];
                        $success = Db::table($entityrow->code)->update($result);
                    }
                    //判断子表数据
                    if ($subformdata) {
                        foreach ($subformdata as $subitem => $subrow) {
                            $subentity = $this->entity->get($subrow['entity_id']);
                            $subfieldListAll = $this->field
                                ->where(['entity_id' => $subrow['entity_id']])
                                ->select();
                            $subresult = [];
                            $subdata = $subrow['data'];
                            foreach ($subfieldListAll as $subi => $subr) {
                                $fieldcode = $subr->fieldcode;
                                $fieldtype = $subr->fieldtype;
                                //判断是否存在数据，在判断是否是子表通过是不是数组判断
                                if ((array_key_exists($fieldcode, $subdata[0]))) {
                                    switch ($fieldtype) {
                                        case 'lookup':
                                            $subresult[$fieldcode] = $subdata[$fieldcode]['id'];
                                            break;
                                        case 'image':
                                        case 'file':
                                            if (is_array($subdata[$fieldcode])) {
                                                $fiellist =$subdata[$fieldcode];
                                                foreach($fiellist as $file){
                                                    if(!empty($file['response'])){
                                                        $file['url'] = $file['response']['url'];
                                                    }
                                                }
                                                $subresult[$fieldcode] = json_encode($subdata[$fieldcode]);
                                            }
                                            break;
                                        case 'subform';
                                            break;
                                        default:
                                            $subresult[$fieldcode] = $subdata[$fieldcode];
                                            break;
                                    }
                                }
                            }
                            if (!$subresult)
                                continue;
                            if ($action == 'add' && $successid != '') {
                                //保存子表
                                $subresult[$fieldcode . '_parentid'] = $successid;
                                $success = Db::table($subentity->code)->insertGetId($subresult);
                            } else {
                                $subresult[$fieldcode . '_parentid'] = $params['id'];
                                $success = Db::table($subentity->code)->update($subresult);
                            }
                        }
                    }
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**删除实体 */
    public function delete($ids = null, $entity_id = null)
    {
        if (!$entity_id) {
            return json('缺少参数', 500);
        }
        if ($ids) {
            $entity = $this->entity->get($entity_id);
            $count = 0;
            Db::startTrans();
            try {
                foreach ($ids as $k) {
                    $count = Db::table($entity->code)->delete($k);
                }
                Db::commit();
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                $this->success();
            } else {
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }

    /** 软删除 */
    public function status()
    {
        $data = $this->request->post('data/a');
        $entity_id = $data['entity_id'];
        $status = $data['status'];
        $ids = $data['ids'];
        if (!$entity_id || !$status || !$ids) {
            return json('缺少参数', 500);
        }
        if ($ids) {
            $entity = $this->entity->get($entity_id);
            $count = 0;
            Db::startTrans();
            try {
                foreach ($ids as $k) {
                    Db::table($entity->code)->where(['id' => $k])->update(['status' => $status]);
                }
                Db::commit();
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                return json(array('code' => 500, 'msg' => 'fail'));
            } else {
                return json(array('code' => 500, 'msg' => 'fail'));
            }
        }
        return json(array('code' => 200, 'msg' => 'success'));
    }

    /**
     * 获取流水号
     */
    public function getnumber($entity_id)
    {
        $row = Db::name('lowcode_number')->where(['entityname' => $entity_id])->find();
        if (!$row) {
            return '';
        }
        $serial_no = '';
        $serial_no .= $row['pre'];
        if ($row['year'] == '是') {
            $serial_no .= Date('Y');
        }
        if ($row['month'] == '是') {
            $serial_no .= Date('m');
        }
        $serial_no .= str_pad($row['index'], $row['lengh'], "0", STR_PAD_LEFT);
        $row->allowField(true)->save(['index' => ($row['index'] + 1)]);
        return $serial_no;
    }



    /**
     * 上传文件
     */
    public function upload()
    {
        $domain = $this->request->domain() . config('view_replace_str.__PUBLIC__');
        Config::set('default_return_type', 'json');
        $file = $this->request->file('image');
        if (empty($file)) {

            $file = $this->request->file('file');
        }
        if (empty($file)) {
            $this->error(__('No file upload or server upload limit exceeded'));
        }
        //判断是否已经存在附件
        $sha1 = $file->hash();
        $extparam = $this->request->post();

        $upload = Config::get('upload');

        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
        $type = strtolower($matches[2]);
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        $size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
        $fileInfo = $file->getInfo();
        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        $suffix = $suffix ? $suffix : 'file';

        $mimetypeArr = explode(',', strtolower($upload['mimetype']));
        $typeArr = explode('/', $fileInfo['type']);

        //验证文件后缀
        if (
            $upload['mimetype'] !== '*' &&
            (!in_array($suffix, $mimetypeArr)
                || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))))
        ) {
            $this->error(__('Uploaded file format is limited'));
        }
        $replaceArr = [
            '{year}'     => date("Y"),
            '{mon}'      => date("m"),
            '{day}'      => date("d"),
            '{hour}'     => date("H"),
            '{min}'      => date("i"),
            '{sec}'      => date("s"),
            '{random}'   => Random::alnum(16),
            '{random32}' => Random::alnum(32),
            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
            '{suffix}'   => $suffix,
            '{.suffix}'  => $suffix ? '.' . $suffix : '',
            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
        ];
        $savekey = $upload['savekey'];
        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
        $fileName = substr($savekey, strripos($savekey, '/') + 1);
        //
        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
        if ($splInfo) {
            $imagewidth = $imageheight = 0;
            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) {
                $imgInfo = getimagesize($splInfo->getPathname());
                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
            }
            $params = array(
                'admin_id'    => (int)$this->auth->id,
                'user_id'     => 0,
                'filesize'    => $fileInfo['size'],
                'imagewidth'  => $imagewidth,
                'imageheight' => $imageheight,
                'imagetype'   => $suffix,
                'imageframes' => 0,
                'mimetype'    => $fileInfo['type'],
                'url'         => $uploadDir . $splInfo->getSaveName(),
                'uploadtime'  => time(),
                'storage'     => 'local',
                'sha1'        => $sha1,
                'extparam'    => json_encode($extparam),
            );
            $attachment = model("attachment");
            $attachment->data(array_filter($params));
            $attachment->save();
            \think\Hook::listen("upload_after", $attachment);
            $result = array('code' => 0, 'url' => rtrim($domain, '/') . $uploadDir . $splInfo->getSaveName());
            return json($result);
        } else {
            $result = array('code' => 500, 'url' => '');
            // 上传失败获取错误信息
            return json($result);
        }
    }

    /**
     * 导入
     */
    public function vxeimport()
    {
        $entity_id = $this->request->request('entity_id');
        $entityrow = Db::name('lowcode_entity')->where(['id' => 'entity_id'])->find();
        $domain = $this->request->domain() . config('view_replace_str.__PUBLIC__');
        Config::set('default_return_type', 'json');
        $file = $this->request->file('image');
        $file = $this->request->file('file');
        if (empty($file)) {
            $this->error(__('No file upload or server upload limit exceeded'));
        }
        //判断是否已经存在附件
        $sha1 = $file->hash();
        $extparam = $this->request->post();

        $upload = Config::get('upload');
        $result = [];
        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
        $type = strtolower($matches[2]);
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        $size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
        $fileInfo = $file->getInfo();
        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        $suffix = $suffix ? $suffix : 'file';

        $mimetypeArr = explode(',', strtolower($upload['mimetype']));
        $typeArr = explode('/', $fileInfo['type']);

        //验证文件后缀
        if (
            $upload['mimetype'] !== '*' &&
            (!in_array($suffix, $mimetypeArr)
                || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))))
        ) {
            $this->error(__('Uploaded file format is limited'));
        }
        $replaceArr = [
            '{year}'     => date("Y"),
            '{mon}'      => date("m"),
            '{day}'      => date("d"),
            '{hour}'     => date("H"),
            '{min}'      => date("i"),
            '{sec}'      => date("s"),
            '{random}'   => Random::alnum(16),
            '{random32}' => Random::alnum(32),
            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
            '{suffix}'   => $suffix,
            '{.suffix}'  => $suffix ? '.' . $suffix : '',
            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
        ];
        $savekey = $upload['savekey'];
        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

        $uploadDir = substr($savekey, 0, strripos($savekey, '\\') + 1);
        $fileName = substr($savekey, strripos($savekey, '\\') + 1);
        //
        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
        if ($splInfo) {
            $imagewidth = $imageheight = 0;
            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) {
                $imgInfo = getimagesize($splInfo->getPathname());
                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
            }
            $params = array(
                'admin_id'    => (int)$this->auth->id,
                'user_id'     => 0,
                'filesize'    => $fileInfo['size'],
                'imagewidth'  => $imagewidth,
                'imageheight' => $imageheight,
                'imagetype'   => $suffix,
                'imageframes' => 0,
                'mimetype'    => $fileInfo['type'],
                'url'         => $uploadDir . $splInfo->getSaveName(),
                'uploadtime'  => time(),
                'storage'     => 'local',
                'sha1'        => $sha1,
                'extparam'    => json_encode($extparam),
            );
            $attachment = model("attachment");
            $attachment->data(array_filter($params));
            $attachment->save();
            \think\Hook::listen("upload_after", $attachment);
            $result = array('code' => 0, 'url' => $uploadDir . $splInfo->getSaveName());
        } else {
            // 上传失败获取错误信息
            $this->error($file->getError());
        }
        $filePath = ROOT_PATH . DS . 'public' . DS . $fileName;
        if (!is_file($filePath)) {
            $this->error(__('No results were found'));
        }
        //实例化reader
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
            $this->error(__('Unknown data format'));
        }
        if ($ext === 'csv') {
            $file = fopen($filePath, 'r');
            $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
            $fp = fopen($filePath, "w");
            $n = 0;
            while ($line = fgets($file)) {
                $line = rtrim($line, "\n\r\0");
                $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
                if ($encoding != 'utf-8') {
                    $line = mb_convert_encoding($line, 'utf-8', $encoding);
                }
                if ($n == 0 || preg_match('/^".*"$/', $line)) {
                    fwrite($fp, $line . "\n");
                } else {
                    fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
                }
                $n++;
            }
            fclose($file) || fclose($fp);

            $reader = new Csv();
        } elseif ($ext === 'xls') {
            $reader = new Xls();
        } else {
            $reader = new Xlsx();
        }

        //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
        $importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';

        $table = $entityrow->code;
        $database = \think\Config::get('database.database');
        $fieldArr = [];
        $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
        foreach ($list as $k => $v) {
            if ($importHeadType == 'comment') {
                $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
            } else {
                $fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
            }
        }

        //加载文件
        $insert = [];
        try {
            if (!$PHPExcel = $reader->load($filePath)) {
                $this->error(__('Unknown data format'));
            }
            $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
            $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
            $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
            $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
            $fields = [];
            for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
                for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
                    $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
                    $fields[] = $val;
                }
            }

            for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
                $values = [];
                for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
                    $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
                    $values[] = is_null($val) ? '' : $val;
                }
                $row = [];
                $temp = array_combine($fields, $values);
                foreach ($temp as $k => $v) {
                    if (isset($fieldArr[$k]) && $k !== '') {
                        $row[$fieldArr[$k]] = $v;
                    }
                }
                if ($row) {
                    $insert[] = $row;
                }
            }
        } catch (Exception $exception) {
            $this->error($exception->getMessage());
        }
        if (!$insert) {
            $this->error(__('No rows were updated'));
        }

        try {
            //是否包含admin_id字段
            $has_admin_id = false;
            foreach ($fieldArr as $name => $key) {
                if ($key == 'admin_id') {
                    $has_admin_id = true;
                    break;
                }
            }
            if ($has_admin_id) {
                $auth = Auth::instance();
                foreach ($insert as &$val) {
                    if (!isset($val['admin_id']) || empty($val['admin_id'])) {
                        $val['admin_id'] = $auth->isLogin() ? $auth->id : 0;
                    }
                }
            }
            $this->model->saveAll($insert);
        } catch (PDOException $exception) {
            $msg = $exception->getMessage();
            if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
                $msg = "导入失败,包含【{$matches[1]}】的记录已存在";
            };
            $this->error($msg);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }

        $this->success();
    }

    public function isJson($data = '', $assoc = true)
    {
        $res = json_decode($data, $assoc);
        if (($res && is_object($res)) || (is_array($res) && !empty($res))) {
            return $res;
        }
        return $data;
    }
}
